跳到主要内容

[toc]

python基础二十五 并发编程-多协程

1.协程

1.1 概念

协程是比线程更小的执行单元,也叫微线程

一个线程作为一个容器里面可以放置多个协程

1.2 协程作用

只切换函数调用即可完成多线程,可以减少CPU的切换

协程自己主动让出CPU,不需要系统调用

1.3 协程实现

1.3.1 greenlet(第三方模块,手动切换函数执行)

#协程间来回切换,不需要CPU的调用
#需要先安装greenlet
pip install greenlet

from greenlet import greenlet
import time
def t1():
while True:
print("AAA") #第一步先打印AAA
gr2.switch() #第二步让协程gr2进来执行,gr1保留此处的执行位置,协程gr2执行的是t2函数
time.sleep(1)


def t2():
while True:
print("bbb") #第三步打印bbb
gr1.switch() #第四步让协程gr1进来执行,gr2保留此处的执行位置,协程gr1执行的是t1函数
time.sleep(1)

gr1 = greenlet(t1) #创建一个协程对象
gr2 = greenlet(t2)
gr1.switch() #此时会执行t1函数


结果:
循环打印
AAA
bbb

1.3.2 gevent(第三方模块,自动切换函数执行)

  • 概念

    gevent是一个能够自动切换函数执行的协程模块,比greenlet功能强大

  • 原理

    gevent通过greenlet实现协程,当一个greenlet遇到IO操作时,就自动切换到其他的greenlet,等待IO操作完成,再在适当的时候切换回来继续执行

  • 特点

    gevent只有遇到模块能够识别的IO操作的时候,程序才会进行任务切换,实现并发效果

#需要先安装gevent
pip install gevent


//代码示例1 无限循环切换协程
import gevent
def A():
while True:
print(".........A.........")
gevent.sleep(1)#用来模拟一个耗时操作
#gevent中:当一个协程遇到耗时操作会自动交出控制权给其他协程
def B():
while True:
print(".........B.........")
gevent.sleep(1) #每当遇到耗时操作,会自用转到其他协程
g1 = gevent.spawn(A) #创建一个gevent对象(创建了一个协程),此时就已经开始执行函数A
g2 = gevent.spawn(B)
g1.join() #等待协程执行结束
g2.join() #会等待协程运行结束后再退出

结果:
无限循环打印
.........A.........
.........B.........
。。。


//代码示例2 控制协程循环次数
import gevent
def A():
for i in range(10):
print("AAA")
gevent.sleep(1)

def B():
for i in range(10):
print("BBB")
gevent.sleep(1)

g1 = gevent.spawn(A)
g2 = gevent.spawn(B)
g1.join()
g2.join()

结果:
打印10
AAA
BBB

进程、线程、协程之间的区别

  • 进程 最小的资源单位,内存级别,如果进程中没有线程只是划分了一个空间
  • 线程 最小的运行单位,cpu级别,进程在执行,实际上是线程在执行
  • 协程 微线程 用户级别 操作系统不知道什么是协程,是程序员yy出来的,欺骗操作系统,因为有IO操作,操作系统会回收权限,协程就是在用户级别将多个任务做成一个任务,但凡有一个线程有IO,手动切换,让线程能获得更大占用系统资源的机会,提高单线程效率